#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>
using namespace std;

#include "BolckQueue.hpp"

int a = 10;

class Data
{
public:
    Data(string* name,int& num, BlockQueue<int>& bq)
    :_name(name),_num(num),_bq(bq)
    {
        
    }
    string* _name;
    int& _num;
    BlockQueue<int>& _bq; 
};

void* Consumer(void* args)
{
    Data* p = (Data*)args;
    while(true)
    {
        int data;
        p->_bq.pop(&data);
        cout << "Consumer consum Data is " << data << endl;
        // //cout << "Consumer " << *(p->_name) << ' ' << p->_num << endl;
        // cout << "Consumer " << p->_bq << endl;
        // //p->_num--;  
        sleep(1);
    }
}

void* Productor(void* args)
{
    Data* p = (Data*)args;
    int cnt = 1;
    while(true)
    {
        p->_bq.Enqueue(cnt);
        cout << "Productor product Data is " << cnt << endl;
        cnt++;
        //cout << "Productor " << *(p->_name) << ' ' << p->_num << endl;
        // cout << "Productor " << p->_bq << endl;
        // //p->_num--;
        // sleep(1);
    }
}

void StartConsumer(vector<pthread_t>& tidsthread,int num,BlockQueue<int>& bq)
{
    for(int i = 0; i < num; i++)
    {
        pthread_t tid;
        string* nameptr = new string("Thread-");
        (*nameptr) += to_string(i + 1);

        Data* p = new Data(nameptr,a,bq);

        pthread_create(&tid,nullptr,Consumer,(void*)p);
        tidsthread.push_back(tid);
    }
}


void StartProductor(vector<pthread_t>& tidsthread,int num,BlockQueue<int>& bq)
{
    for(int i = 0; i < num; i++)
    {
        pthread_t tid;
        string* nameptr = new string("Thread-");
        *nameptr += to_string(i + 1);

        Data* p = new Data(nameptr,a,bq);

        pthread_create(&tid,nullptr,Productor,(void*)p);
        tidsthread.push_back(tid);
    }
}

void WaitAllThread(vector<pthread_t>& tidsthread)
{
    for(auto& e:tidsthread)
    {
        pthread_join(e,nullptr);
    }
}

int main()
{
    vector<pthread_t> tids;
    BlockQueue<int>* bq = new BlockQueue<int>(6);

    StartConsumer(tids,2,*bq);
    StartProductor(tids,3,*bq);

    WaitAllThread(tids);

    return 0;
}

